package han.chensing.latos.res;

import com.badlogic.gdx.Application;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.utils.Disposable;

import java.util.HashMap;
import java.util.Map;
import java.util.Queue;
import java.util.Set;
import java.util.concurrent.LinkedBlockingQueue;

@SuppressWarnings("SameParameterValue")
public class Res {
    private static Res res;
    private final HashMap<String,Object> resources;
    private final Queue<LoadEntry> loadEntries;
    private int loadTotal=0;
    private int loadedTotal=0;
    public static Res getInstance(){
        if (res==null)
            res=new Res();
        return res;
    }

    public Res(){
        resources=new HashMap<>();
        loadEntries=new LinkedBlockingQueue<>();
    }

    public void fakeLoadAll(){
        //Open it until it's available
        //V.setting=Setting.fromFile();
        String soundType=Gdx.app.getType()== Application.ApplicationType.Android?".pcm":".wav";
        fakeLoadTTFGenerator("fontConsolasGenerator","game/font/consola.ttf");
        fakeLoadTTF("fontConsolas50","fontConsolasGenerator",50);
        fakeLoadTTF("fontConsolas20","fontConsolasGenerator",30);
        fakeLoadSound("tapSound", "game/sound/hitSong0"+soundType);
        fakeLoadSound("dragSound", "game/sound/hitSong1"+soundType);
        fakeLoadSound("flickSound","game/sound/hitSong2"+soundType);
        fakeLoadTexture("effectPerfectT","game/effects/perfect.png");
        fakeLoadTexture("effectCorruptPerfectT","game/effects/corruptPerfect.png");
        fakeLoadTexture("effectGoodT","game/effects/good.png");
        fakeLoadTexture("effectCorruptGoodT","game/effects/corruptGood.png");
        fakeLoadAnimation("effectPerfect","effectPerfectT",512,512);
        fakeLoadAnimation("effectCopPerfect","effectCorruptPerfectT",512,512);
        fakeLoadAnimation("effectGood","effectGoodT",512,512);
        fakeLoadAnimation("effectCopGood","effectCorruptGoodT",512,512);
        fakeLoadTexturePair("tapNote","game/notes/tapNote.png");
        fakeLoadTexturePair("dragNote","game/notes/dragNote.png");
        fakeLoadTexturePair("flickNote","game/notes/flickNote.png");
        fakeLoadTexturePair("directFlickNoteDown","game/notes/directFlickNoteDown.png");
        fakeLoadTexturePair("directFlickNoteUp","game/notes/directFlickNoteUp.png");
        fakeLoadTexturePair("holdNoteHead","game/notes/holdNoteHead.png");
        fakeLoadTexturePair("holdNoteBody","game/notes/holdNoteBody.png");
        fakeLoadTexturePair("holdNoteEnd","game/notes/holdNoteEnd.png");
        fakeLoadTexturePair("effectBad","game/effects/badNoteEffect.png");
        fakeLoadTexturePair("effectEmpty","game/effects/effect.png");
    }

    public void load(String name,Object o){
        resources.put(name,o);
    }

    public boolean readLoadSingle(){
        LoadEntry poll = loadEntries.poll();
        if (poll==null)return true;
        loadedTotal++;
        load(poll.name,poll.realLoad(res));
        return false;
    }

    public void disposeAll(){
        Set<Map.Entry<String, Object>> entries = resources.entrySet();
        for(Map.Entry<String,Object> entry:entries){
            if (entry.getValue() instanceof Disposable){
                Disposable disposable = (Disposable) entry.getValue();
                disposable.dispose();
            }
        }
    }

    @SuppressWarnings({"unchecked", "unused"})
    public <T> T get(String name,Class<T> tClass){
        return (T)resources.get(name);
    }

    public int getLoadTotal() {
        return loadTotal;
    }

    public int getLoadedTotal() {
        return loadedTotal;
    }

    private void fakeLoadTexturePair(String name, String path){
        fakeLoadTexture(name+"T",path);
        fakeLoadTextureRegion(name,name+"T");
    }

    private void fakeLoadTexture(String name,String path){
        loadTotal++;
        loadEntries.offer(new LoadEntry.TextureEntry(name, path));
    }

    private void fakeLoadTextureRegion(String name,String textureName){
        loadTotal++;
        loadEntries.offer(new LoadEntry.TextureRegionEntry(name, textureName));
    }

    private void fakeLoadSound(String name,String path){
        loadTotal++;
        loadEntries.offer(new LoadEntry.SoundRegionEntry(name, path));
    }

    private void fakeLoadAnimation(String name,String textureName,int width,int height){
        loadTotal++;
        loadEntries.offer(new LoadEntry.AnimationEntry(name,textureName,width,height));
    }

    private void fakeLoadTTFGenerator(String name,String path){
        loadTotal++;
        loadEntries.offer(new LoadEntry.TTFGeneratorEntry(name, path));
    }

    private void fakeLoadTTF(String name,String generatorName,int size){
        loadTotal++;
        loadEntries.offer(new LoadEntry.TTFEntry(name, generatorName, size));
    }
}
